<?php

class Auth
{
    /**
     * http://8.134.81.238:8080/index.php?type=login
     * 用户登录，根据用户姓名和密码来获取用户信息，然后返回给用户token
     * @param username 用户名称
     * @param password 用户密码
     * @return string
     */
    public static function login()
    {
        // 查询配置文件获取用户信息
        if ($_GET['username']) {
            $username = $_GET['username'];
        } else {
            echo '请输入用户姓名';
        }

        if ($_GET['password']) {
            $password = $_GET['password'];
        } else {
            echo '请输入用户密码';
        }
        $passwordConfig = config::get('users')[$username];
        if ($password != $passwordConfig) {
            echo '用户密码不正确';
        }

        $time = time(); //当前时间
        $token = [
            'iat' => $time, //签发时间
            'nbf' => $time, //(Not Before)：某个时间点后才能访问，比如设置time+30，表示当前时间30秒后才能使用
            'exp' => $time + 3600, // token有效期为1个小时
            'data' => [
                'username' => $username, // 用户姓名
            ]];
        $jwtToken = \Firebase\JWT\JWT::encode($token, config::get('key'));
        return $jwtToken; // 返回给用户
    }

    /**
     * 用户身份认证
     * @param token 登录返回的token
     * @param appid 应用id
     * @param request_time 请求时间
     * @param random_number 随机码
     * @param sign 签名，签名规则：
     */
    public static function authentication()
    {

        if ($_SERVER['HTTP_TOKEN']) {
            $token = $_SERVER['HTTP_TOKEN'];
            $all_params['token'] = $token;
        } else {
            echo 'token缺失,请先登录';
        }

        // 验证是否过期
        $tokenInfo = \Firebase\JWT\JWT::decode($all_params['token'],config::get('key'));

        if ($tokenInfo['exp'] < time()) {
            echo 'token过期，请重新登录';
        }

        if ($_GET['appid']) {
            $appid = $_GET['appid'];
            $all_params['appid'] = $appid;
        } else {
            echo 'appid缺失';
        }

        if ($_GET['request_time']) {
            $request_time = $_GET['request_time'];
            $all_params['request_time'] = $request_time;
        } else {
            echo 'request_time缺失';
        }

        if ($_GET['random_number']) { // 随机码保证请求的唯一性
            $random_number = $_GET['random_number'];
            $all_params['random_number'] = $random_number;
        } else {
            echo 'random_number缺失';
        }

        //记录每次请求的uuid，如果uuid已存在于redis中，则该次请求无效。
        //配置连接的IP、端口、以及相应的数据库
        $redisConfig = array (
            'host'     => '127.0.0.1',
            'port'     => 6379,
            'database' => 15
        );
        $redis = new \Predis\Client($redisConfig);
        $request_uuid = $redis->sismember('uuid', $_GET['random_number']); // 需要从redis中获取
        if ($request_uuid) { // 如果uuid存在，则结束处理请求
            echo '重复请求';
        } else {
            // 插入请求到redis中，保证唯一性
            $redis->sadd('uuid', $_GET['random_number']);
            $redis->expire('uuid', 10); // 10秒内重复请求

        }

        // appid和秘钥对应关系
        $secret = config::get('apps')[$appid];

        if ($_GET['sign']) {
            $sign = $_GET['sign'];
        } else {
            echo 'sign丢失';
        }

        $all_params['secret'] = $secret;

        ksort($all_params);
        $sign_key = '';
        foreach ($all_params as $k => $v) {
            $sign_key .= $k .= '=' . $v . '&';
        }
        $sign_key = substr_replace($sign_key, "", -1); // 去掉末尾&符号
        $md_sign = md5($sign_key);
        if ($sign !== $md_sign) {
            echo '签名验证失败';
        }
        // 注意： 为防止重复请求，建议由前端每次传入 uuid ，根据 uuid 请求是否重复。

        // 验证通过后，进行相关的业务逻辑代码处理。
    }

}